package cc.geeksearch.ble

import android.bluetooth.BluetoothDevice
import android.content.Context
import cc.geeksearch.ble.bean.DeviceBean
import cc.geeksearch.ble.bean.ScanItemBean

class Walle(private var context: Context) {
    private val TAG = "Walle"
    private var scanner: WalleScanner? = null
    private var connector: WalleConnector? = null
    private var scannerTargetCallback: ScannerTargetCallback? = null

    init {
        scannerTargetCallback = object : ScannerTargetCallback {
            override fun onScanSuccess(scanItem: ScanItemBean) {
                getConnector().connect(scanItem.device)
            }

            override fun onScanFailed(addressList: List<String>) {
                addressList.forEach { address ->
                    getConnector().updateDevice(DeviceBean(address,"",DeviceStatus.CONNECT_FAILED, "",0))
                }
            }
        }
        getScanner().setScannerTargetCallback(scannerTargetCallback!!)
    }


    companion object {
        private var INSTANCE: Walle? = null

        fun getInstance(context: Context): Walle {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: Walle(context).also { INSTANCE = it }
            }
        }

        fun destroy() {
            INSTANCE = null
        }
    }

    /**
     * 开始扫描
     * @param timeout 扫描超时时间，单位毫秒
     */
    fun startScan(timeout: Long = 10000) {
        getScanner().startScan(timeout)
    }

    /**
     * 停止扫描
     */
    fun stopScan() {
        getScanner().stopScan()
    }

    /**
     * 连接设备
     * @param bluetoothDevice 蓝牙设备
     */
    fun connect(bluetoothDevice: BluetoothDevice) {
        getConnector().connect(bluetoothDevice)
    }

    /**
     * 连接设备
     * @param address 蓝牙设备地址
     */
    fun connect(address: String) {
        val gatt = getConnector().getConnected(address)
        if (gatt != null) {
            getConnector().connect(gatt.device)
        } else {
            getConnector().updateDevice(DeviceBean(address,"",DeviceStatus.CONNECTING, "",0))
            getScanner().startScan(10000, address)
        }
    }

    fun disconnect(address: String) {
        getConnector().disconnect(address)
    }

    fun remark(address: String, remark: String) {
        WalleLog.d(TAG, "$address, remark:  $remark")
        getConnector().remark(address, remark)
    }

    /**
     * 删除设备
     * @param address 蓝牙设备地址
     */
    fun delete(address: String) {
        getConnector().delete(address)
    }

    /**
     * 删除所有设备
     */
    fun deleteAll() {
        getConnector().deleteAll()
    }

    /**
     * 获取绑定的设备列表
     */
    fun getDevices() {
        getConnector().getDevices()
    }

    fun getServiceUUIDS(address: String) {
        getConnector().getServiceUUIDS(address)
    }

    fun sendData(
        address: String,
        serviceUUID: String,
        characteristicUUID: String,
        data: ByteArray
    ) {
        // 打印十六进制内容
        val hexString = data.joinToString(" ") { "%02X".format(it) }
        WalleLog.d(TAG, "发送数据：$hexString")
        getConnector().sendData(address, serviceUUID, characteristicUUID, data)
    }

    fun subscribe(address: String, serviceUUID: String, characteristicUUID: String) {
        getConnector().subscribe(address, serviceUUID, characteristicUUID)
    }

    fun unsubscribe(address: String, serviceUUID: String, characteristicUUID: String) {
        getConnector().unsubscribe(address, serviceUUID, characteristicUUID)
    }

    fun read(address: String, serviceUUID: String, characteristicUUID: String) {
        getConnector().read(address, serviceUUID, characteristicUUID)
    }

    private fun getScanner(): WalleScanner {
        if (scanner != null) {
            return scanner as WalleScanner
        }
        scanner = WalleScanner(context)
        return scanner as WalleScanner
    }

    private fun getConnector(): WalleConnector {
        if (connector != null) {
            return connector as WalleConnector
        }
        connector = WalleConnector(context)
        return connector as WalleConnector
    }
}